﻿// DrawingBoard20220777View.cpp: CDrawingBoard20220777View 类的实现
//

#include "pch.h"
#include "framework.h"
#include <vector>
#include <cmath>
#include <ctime>
#include <atlimage.h> // 添加ATL图像支持
#define M_PI 3.14159265358979323846 // 定义圆周率常量
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义，并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "DrawingBoard20220777.h"
#endif

#include "DrawingBoard20220777Doc.h"
#include "DrawingBoard20220777View.h"
#include "resource.h"
#include "setSize.h"
#include <stack>
// 添加资源ID定义
#define ID_UNDO            32800
#define ID_RELOAD          32801
#define ID_SPRAY           32802
#define ID_COLOR_PICKER    32803

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
# include "Test.h"


// CDrawingBoard20220777View

IMPLEMENT_DYNCREATE(CDrawingBoard20220777View, CView)

BEGIN_MESSAGE_MAP(CDrawingBoard20220777View, CView)
    // 标准打印命令
    ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
    ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
    ON_WM_LBUTTONDOWN()
    ON_WM_MOUSEMOVE()
    ON_WM_LBUTTONUP()
    ON_WM_ERASEBKGND() // 添加此行
    ON_COMMAND(ID_32773, &CDrawingBoard20220777View::OnLine)
    ON_COMMAND(ID_32774, &CDrawingBoard20220777View::OnRectangle)
    ON_COMMAND(ID_32771, &CDrawingBoard20220777View::OnCircle)
    ON_COMMAND(ID_32772, &CDrawingBoard20220777View::OnEllipse)
    ON_COMMAND(ID_32776, &CDrawingBoard20220777View::OnSetColor)
    ON_COMMAND(ID_32775, &CDrawingBoard20220777View::OnSetPenSize)
    ON_COMMAND(ID_32778, &CDrawingBoard20220777View::OnSetPencil)
    ON_COMMAND(ID_32779, &CDrawingBoard20220777View::OnSetEraser)
    ON_COMMAND(ID_32781, &CDrawingBoard20220777View::OnFileOpen)
    ON_COMMAND(ID_32782, &CDrawingBoard20220777View::OnText)
    ON_COMMAND(ID_32783, &CDrawingBoard20220777View::OnMagnify)
    ON_COMMAND(ID_32800, &CDrawingBoard20220777View::OnUndo)
    ON_COMMAND(ID_32801, &CDrawingBoard20220777View::OnReload)
    ON_COMMAND(ID_32802, &CDrawingBoard20220777View::OnSpray)
    ON_COMMAND(ID_32803, &CDrawingBoard20220777View::OnColorPicker)
    ON_COMMAND(ID_Background, &CDrawingBoard20220777View::OnSetBackgroundColor)

    ON_COMMAND(ID_SHAPE_ROUNDED_RECT, &CDrawingBoard20220777View::OnShapeRoundedRect)
    ON_COMMAND(ID_SHAPE_HEART, &CDrawingBoard20220777View::OnShapeHeart)
    ON_COMMAND(ID_SHAPE_STAR, &CDrawingBoard20220777View::OnShapeStar)
    ON_COMMAND(ID_SHAPE_Hexagram, &CDrawingBoard20220777View::OnShapeHexagram)
    ON_COMMAND(ID_SHAPE_UP_ARROW, &CDrawingBoard20220777View::OnShapeUpArrow)
    ON_COMMAND(ID_SHAPE_DOWN_ARROW, &CDrawingBoard20220777View::OnShapeDownArrow)
    ON_COMMAND(ID_SHAPE_LEFT_ARROW, &CDrawingBoard20220777View::OnShapeLeftArrow)
    ON_COMMAND(ID_SHAPE_RIGHT_ARROW, &CDrawingBoard20220777View::OnShapeRightArrow)
    ON_COMMAND(ID_SHAPE_CLOUD, &CDrawingBoard20220777View::OnShapeCloud)
    ON_COMMAND(ID_SHAPE_WAVE, &CDrawingBoard20220777View::OnShapeWave)
    ON_COMMAND(ID_SHAPE_WILLOW_LEAF, &CDrawingBoard20220777View::OnShapeWillowLeaf)
    ON_COMMAND(ID_SHAPE_DIAMOND, &CDrawingBoard20220777View::OnShapeDiamond)
    ON_COMMAND(ID_SHAPE_HEXAGON, &CDrawingBoard20220777View::OnShapeHexagon)
    ON_COMMAND(ID_SHAPE_PENTAGON, &CDrawingBoard20220777View::OnShapePentagon)
    ON_COMMAND(ID_SHAPE_bomb, &CDrawingBoard20220777View::OnShapebomb)
    ON_COMMAND(ID_PaintBucket, &CDrawingBoard20220777View::OnFillColor)
    ON_COMMAND(ID_DL, &CDrawingBoard20220777View::On_SDL_OnDraw)
    ON_COMMAND(ID_DLPro, &CDrawingBoard20220777View::On_SDProL_OnDraw)
END_MESSAGE_MAP()


// CDrawingBoard20220777View 构造/析构
bool isMy = false; // 是否使用自定义椭圆绘制
CDrawingBoard20220777View::CDrawingBoard20220777View() noexcept :
    centerX(0), 
    centerY(0), 
    scale(1.0f), 
    headWidth(0), 
    headHeight(0), 
    headOffsetX(150),
    headOffsetY(50)
{
    // TODO: 在此处添加构造代码

    m_PenSize = 1;
    m_PenColor = RGB(0, 0, 0);
    m_BrushColor = RGB(0, 0, 0);
    m_PointBegin = CPoint(0, 0);
    m_PointEnd = CPoint(0, 0);
    m_DrawType = DrawType::LineSegment;
    m_TextId = 10086;
    m_bDrawing = false;
    m_SprayRadius = 20; // 默认喷墨半径
    m_BackgroundColor = RGB(255, 255, 255);

    // 初始化文本设置
    m_TextSize = 12;  // 默认12点
    m_TextColor = RGB(0, 0, 0); // 黑色
    
    // 创建默认字体
    m_TextFont.CreatePointFont(m_TextSize * 10, _T("宋体"));

    m_FillColor = RGB(0, 0, 255);  // 默认蓝色填充
    m_FillTolerance = 10;          // 默认容差10
    m_FillContiguous = true;       // 默认连续填充
}

CDrawingBoard20220777View::~CDrawingBoard20220777View()
{
    if (m_Edit != nullptr) {
        delete m_Edit;
        m_Edit = nullptr;
    }

    // 清理内存位图
    if (m_MemBitmap.GetSafeHandle() != nullptr)
    {
        m_MemBitmap.DeleteObject();
    }

    // 清理撤销栈
    for (auto hBitmap : m_UndoStack) {
        if (hBitmap != nullptr) {
            DeleteObject(hBitmap);
        }
    }
    m_UndoStack.clear();
}

BOOL CDrawingBoard20220777View::PreCreateWindow(CREATESTRUCT& cs)
{
    // TODO: 在此处通过修改
    //  CREATESTRUCT cs 来修改窗口类或样式

    return CView::PreCreateWindow(cs);
}

// CDrawingBoard20220777View 绘图

void CDrawingBoard20220777View::OnDraw(CDC* pDC)
{
    CDrawingBoard20220777Doc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // 双缓冲绘图
    CRect rect;
    GetClientRect(&rect);

    if (m_MemDC.GetSafeHdc() == nullptr)
    {
        // 初始化内存DC
        CClientDC dc(this);
        m_MemDC.CreateCompatibleDC(&dc);
        m_MemBitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
        m_MemDC.SelectObject(&m_MemBitmap);
        m_MemDC.FillSolidRect(rect, RGB(255, 255, 255)); // 白色背景
    }

    //// 将内存位图绘制到屏幕
    pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &m_MemDC, 0, 0, SRCCOPY);
    if (DL)
    {
        CRect windowRect;
        GetWindowRect(&windowRect);



        // 计算绘图区域的宽度和高度
        int width = windowRect.Width();
        int height = windowRect.Height();

        // 计算中心点，用于定位
        centerX = width / 2;
        centerY = height / 3;

        // 确定缩放因子（使用较小的边作为基准，保持等比例）
        scale = min(width / 1200.0f, height / 800.0f) * 1.25;

        // 保持原始比例关系：头部宽度300，高度300，中心点偏移量
        headWidth = (int)(300 * scale);
        headHeight = (int)(300 * scale);

        // 定义颜色
        COLORREF blue = RGB(0, 160, 230);      // 哆啦A梦蓝色
        COLORREF white = RGB(255, 255, 255);   // 白色
        COLORREF black = RGB(0, 0, 0);         // 黑色
        COLORREF red = RGB(205, 0, 0);         // 红色
        COLORREF yellow = RGB(255, 205, 0);    // 黄色
        COLORREF orange = RGB(255, 130, 40);   // 橙色
        COLORREF pink = RGB(255, 204, 208); // 粉红色
        // 定义所有画笔和画刷
        CPen headPen(PS_SOLID, (int)(3 * scale), black);
        CBrush headBrush(blue);
        CBrush faceBrush(white);
        CBrush eyeBrush(white);
        CBrush pupilBrush(black);
        CBrush pupilBrushLight(white);
        CBrush redBrush(red);
        CPen nullPen(PS_NULL, 0, RGB(0, 0, 0));
        CBrush noseBrushLight(white);
        CPen whiskerPen(PS_SOLID, (int)(2 * scale), black);
        CBrush orangeBrush(orange);
        CBrush whiteBrush(white);
        CBrush blueBrush(blue);

        CPen scarfPen(PS_SOLID, (int)(2 * scale), RGB(150, 0, 0)); // 深红色轮廓
        CBrush scarfBrush(red);
        CPen bellPen(PS_SOLID, (int)(1 * scale), black);
        CBrush bellBrush(yellow);
        CBrush circleBrush(black);
        CPen blushPen(PS_SOLID, 1, pink); // 粉红色边框
        CBrush blushBrush(pink); // 粉红色填充

        // 绘制哆啦A梦头部 (椭圆)
        CPen* pOldPen = pDC->SelectObject(&headPen);
        CBrush* pOldBrush = pDC->SelectObject(&headBrush);

        int leftX = 150, leftY = 50;
        //pDC->Ellipse(CalculateX(150), CalculateY(50), CalculateX(450), CalculateY(350));
        //MyEllipse(pDC, CalculateX(leftX), CalculateY(leftY), CalculateX(leftX + headWidth), CalculateY(leftY + headHeight));
        pDC->Ellipse(CalculateX(leftX), CalculateY(leftY), CalculateX(leftX + headWidth / scale), CalculateY(leftY + headHeight / scale));




        // 绘制脸部白色区域 (椭圆)
        pDC->SelectObject(&faceBrush);
        MyEllipse(pDC, CalculateX(180), CalculateY(110), CalculateX(420), CalculateY(350));

        // 绘制眼睛
        pDC->SelectObject(&eyeBrush);

        // 左眼

        MyEllipse(pDC, CalculateX(240), CalculateY(80), CalculateX(300), CalculateY(160));

        // 右眼（保持与左眼的相对位置）
        MyEllipse(pDC, MirrorX(240), CalculateY(80), MirrorX(300), CalculateY(160));

        // 绘制眼球
        pDC->SelectObject(&pupilBrush);

        // 左眼球
        MyEllipse(pDC, CalculateX(275), CalculateY(105), CalculateX(290), CalculateY(135));

        // 右眼球
        int rightPupilX = (int)(310 * scale);
        MyEllipse(pDC, MirrorX(275), CalculateY(105), MirrorX(290), CalculateY(135));

        // 绘制瞳孔高光
        pDC->SelectObject(&pupilBrushLight);
        pDC->SelectObject(&nullPen);
        // 左眼球高光
        MyEllipse(pDC, CalculateX(280), CalculateY(117), CalculateX(288), CalculateY(130));

        // 右眼球高光
        MyEllipse(pDC, MirrorX(280), CalculateY(117), MirrorX(288), CalculateY(130));

        // 星星眼
        // 
        //int left1X = 250, left1Y = 100, right1X = 260, right1Y = 110,
        //    left2X = 278, left2Y = 115, right2X = 280, right2Y = 125,
        //    left3X = 278, left3Y = 115, right3X = 280, right3Y = 125;
        //// 左眼球上高光
        //MyEllipse(pDC, CalculateX(left1X), CalculateY(left1Y), CalculateX(right1X), CalculateY(right1Y));

        //// 右眼球上高光
        //MyEllipse(pDC, MirrorX(left1X), CalculateY(left1Y), MirrorX(right1X), CalculateY(right1Y));

        //// 左眼球左高光
        //MyEllipse(pDC, CalculateX(left2X), CalculateY(left2Y), CalculateX(right2X), CalculateY(right2Y));

        //// 右眼球右高光
        //MyEllipse(pDC, MirrorX(left2X), CalculateY(left2Y), MirrorX(right2X), CalculateY(right2Y));

        //// 左眼球左高光
        //MyEllipse(pDC, CalculateX(left3X), CalculateY(left3Y), CalculateX(right3X), CalculateY(right3Y));

        //// 右眼球右高光
        //MyEllipse(pDC, MirrorX(left3X), CalculateY(left3Y), MirrorX(right3X), CalculateY(right3Y));



        // 绘制鼻子 (圆形)
        pDC->SelectObject(&redBrush);
        pDC->SelectObject(&headPen);
        int noseLeftX = 282, noseLeftY = 150, noseRightX = 318, noseRightY = 186;
        MyEllipse(pDC, CalculateX(noseLeftX), CalculateY(noseLeftY), CalculateX(noseRightX), CalculateY(noseRightY));

        pDC->SelectObject(&noseBrushLight);

        // 选择空画笔以移除轮廓
        CPen* pOldPenOne = pDC->SelectObject(&nullPen);

        // 鼻子高光

        MyEllipse(pDC, CalculateX(300), CalculateY(160), CalculateX(312), CalculateY(172));

        // 恢复原来的画笔
        pDC->SelectObject(pOldPenOne);

        pDC->SelectObject(&whiskerPen);
        int mouthLeftX = 240, mouthLeftY = 245, mouthRightX = 360, mouthRightY = mouthLeftY + 70;
        // 绘制人中
        pDC->MoveTo(CalculateX(300), CalculateY(noseRightY));
        pDC->LineTo(CalculateX(300), CalculateY(mouthLeftY));


        //// 绘制腮红（两个椭圆）
        //pDC->SelectObject(&blushBrush);

        //pDC->SelectObject(&blushPen);
        //int blushLeftX = 210, blushLeftY = 175, blushRightX = 260, blushRightY = 220;

        //MyEllipse(pDC, CalculateX(blushLeftX), CalculateY(blushLeftY), 
        //    CalculateX(blushRightX), CalculateY(blushRightY));

        //MyEllipse(pDC, MirrorX(blushLeftX), CalculateY(blushLeftY),
        //    MirrorX(blushRightX), CalculateY(blushRightY));


        // 绘制嘴巴

        pDC->SelectObject(&redBrush);

        MyEllipse(pDC, CalculateX(mouthLeftX), CalculateY(mouthLeftY), CalculateX(mouthRightX), CalculateY(mouthRightY));

        // 绘制舌头
        pDC->SelectObject(&orangeBrush);

        MyEllipse(pDC, CalculateX(265), CalculateY(295), CalculateX(335), CalculateY(mouthRightY));

        // 绘制胡须
        pDC->SelectObject(&whiskerPen);
        CPoint Beard1(CalculateX(240), CalculateY(210));
        CPoint Beard2(CalculateX(170), CalculateY(190));
        CPoint Beard3(CalculateX(240), CalculateY(220));
        CPoint Beard4(CalculateX(170), CalculateY(220));
        CPoint Beard5(CalculateX(240), CalculateY(230));
        CPoint Beard6(CalculateX(170), CalculateY(250));
        // 左边胡须
        pDC->MoveTo(Beard1);
        pDC->LineTo(Beard2);

        pDC->MoveTo(Beard3);
        pDC->LineTo(Beard4);

        pDC->MoveTo(Beard5);
        pDC->LineTo(Beard6);

        // 右边胡须
        pDC->MoveTo(MirrorXAbs(Beard1.x), Beard1.y);
        pDC->LineTo(MirrorXAbs(Beard2.x), Beard2.y);

        pDC->MoveTo(MirrorXAbs(Beard3.x), Beard3.y);
        pDC->LineTo(MirrorXAbs(Beard4.x), Beard4.y);

        pDC->MoveTo(MirrorXAbs(Beard5.x), Beard5.y);
        pDC->LineTo(MirrorXAbs(Beard6.x), Beard6.y);

        pDC->SelectObject(&headPen);
        pDC->SelectObject(&whiteBrush);

        // 绘制左脚掌
        pDC->SelectObject(&whiteBrush);
        pDC->SelectObject(&headPen);
        CPoint ptsLeftFoot[7];
        ptsLeftFoot[0] = CPoint(CalculateX(200), CalculateY(525));
        ptsLeftFoot[1] = CPoint(CalculateX(180), CalculateY(540));
        ptsLeftFoot[2] = CPoint(CalculateX(175), CalculateY(560));
        ptsLeftFoot[3] = CPoint(CalculateX(195), CalculateY(570));
        ptsLeftFoot[4] = CPoint(CalculateX(220), CalculateY(580));
        ptsLeftFoot[5] = CPoint(CalculateX(310), CalculateY(590));
        ptsLeftFoot[6] = CPoint(CalculateX(285), CalculateY(537));

        // 绘制左脚贝塞尔曲线
        pDC->BeginPath();
        pDC->MoveTo(ptsLeftFoot[0]);
        pDC->PolyBezierTo(ptsLeftFoot + 1, 6);
        pDC->EndPath();
        pDC->StrokeAndFillPath();

        // 绘制右脚掌
        CPoint ptsRightFoot[7];
        for (int i = 0; i < 7; i++) {
            ptsRightFoot[i] = CPoint(MirrorXAbs(ptsLeftFoot[i].x), ptsLeftFoot[i].y);
        }

        // 绘制右脚贝塞尔曲线
        pDC->BeginPath();
        pDC->MoveTo(ptsRightFoot[0]);
        pDC->PolyBezierTo(ptsRightFoot + 1, 6);
        pDC->EndPath();
        pDC->StrokeAndFillPath();

        pDC->SelectObject(&blueBrush);



        // 绘制左手臂
        CPoint ptsLeftArm[4];
        pDC->SelectObject(&blueBrush);
        ptsLeftArm[0] = CPoint(CalculateX(215), CalculateY(345));
        ptsLeftArm[1] = CPoint(CalculateX(30), CalculateY(470));
        ptsLeftArm[2] = CPoint(CalculateX(145), CalculateY(490));
        ptsLeftArm[3] = CPoint(CalculateX(210), CalculateY(440));

        pDC->BeginPath();
        pDC->MoveTo(ptsLeftArm[0]);
        pDC->PolyBezierTo(ptsLeftArm + 1, 3);
        pDC->EndPath();
        pDC->FillPath();
        pDC->MoveTo(ptsLeftArm[0]);
        pDC->PolyBezierTo(ptsLeftArm + 1, 3);


        // 绘制右手臂
        CPoint ptsRightArm[4];
        for (int i = 0; i < 4; i++) {
            ptsRightArm[i] = CPoint(MirrorXAbs(ptsLeftArm[i].x), ptsLeftArm[i].y);
        }

        pDC->BeginPath();
        pDC->MoveTo(ptsRightArm[0]);
        pDC->PolyBezierTo(ptsRightArm + 1, 3);
        pDC->EndPath();
        pDC->FillPath();
        pDC->MoveTo(ptsRightArm[0]);
        pDC->PolyBezierTo(ptsRightArm + 1, 3);


        CRgn region;
        pDC->BeginPath();
        // 身体左曲线
        CPoint ptsLeftBodyCurve1[4];
        ptsLeftBodyCurve1[0] = CPoint(CalculateX(215), CalculateY(345));

        ptsLeftBodyCurve1[1] = CPoint(CalculateX(190), CalculateY(470));
        ptsLeftBodyCurve1[2] = CPoint(CalculateX(210), CalculateY(500));
        ptsLeftBodyCurve1[3] = CPoint(CalculateX(200), CalculateY(530));

        pDC->MoveTo(ptsLeftBodyCurve1[0]);
        pDC->PolyBezierTo(ptsLeftBodyCurve1 + 1, 3);

        // 身体左脚背
        CPoint ptsLeftFootTop[4];
        ptsLeftFootTop[0] = CPoint(CalculateX(200), CalculateY(530));
        ptsLeftFootTop[1] = CPoint(CalculateX(225), CalculateY(537));
        ptsLeftFootTop[2] = CPoint(CalculateX(250), CalculateY(544));
        ptsLeftFootTop[3] = CPoint(CalculateX(284), CalculateY(537));

        pDC->MoveTo(ptsLeftFootTop[0]);
        pDC->PolyBezierTo(ptsLeftFootTop + 1, 3);

        // 身体左内曲线
        CPoint ptsLeftBodyCurve2[4];
        ptsLeftBodyCurve2[0] = CPoint(CalculateX(284), CalculateY(537));
        ptsLeftBodyCurve2[1] = CPoint(CalculateX(288), CalculateY(523));
        ptsLeftBodyCurve2[2] = CPoint(CalculateX(296), CalculateY(512));
        ptsLeftBodyCurve2[3] = CPoint(CalculateX(headWidth / (2 * scale) + headOffsetX), CalculateY(510));

        pDC->MoveTo(ptsLeftBodyCurve2[0]);
        pDC->PolyBezierTo(ptsLeftBodyCurve2 + 1, 3);


        // 身体右内曲线
        CPoint ptsRightBodyCurve2[4];
        for (int i = 0; i < 4; i++) {
            ptsRightBodyCurve2[i] = CPoint(MirrorXAbs(ptsLeftBodyCurve2[3 - i].x), ptsLeftBodyCurve2[3 - i].y);
        }
        pDC->MoveTo(ptsRightBodyCurve2[0]);
        pDC->PolyBezierTo(ptsRightBodyCurve2 + 1, 3);

        // 身体右脚背
        CPoint ptsRightFootTop[4];
        for (int i = 0; i < 4; i++) {
            ptsRightFootTop[i] = CPoint(MirrorXAbs(ptsLeftFootTop[3 - i].x), ptsLeftFootTop[3 - i].y);
        }

        pDC->MoveTo(ptsRightFootTop[0]);
        pDC->PolyBezierTo(ptsRightFootTop + 1, 3);


        // 身体右曲线
        CPoint ptsRightBodyCurve1[4];
        for (int i = 0; i < 4; i++) {
            ptsRightBodyCurve1[i] = CPoint(MirrorXAbs(ptsLeftBodyCurve1[3 - i].x), ptsLeftBodyCurve1[3 - i].y);
        }

        pDC->MoveTo(ptsRightBodyCurve1[0]);
        pDC->PolyBezierTo(ptsRightBodyCurve1 + 1, 3);




        // 连接左右点
        CPoint ptsConnect[2];
        ptsConnect[0] = CPoint(ptsRightArm[0]);
        ptsConnect[1] = CPoint(MirrorXAbs(ptsRightArm[0].x), ptsRightArm[0].y);
        pDC->MoveTo(ptsConnect[0]);
        pDC->LineTo(ptsConnect[1]);


        // 绘制路径
        pDC->EndPath();
        region.CreateFromPath(pDC); // 路径转区域
        pDC->FillRgn(&region, &blueBrush); // 填充区域
        region.DeleteObject(); // 释放区域资源


        // 定义身体区域顶点（左侧 + 右侧对称点）
        CPoint bodyPts[] = {
            // 左侧顶点
            CPoint(CalculateX(215), CalculateY(345)),
            CPoint(CalculateX(200), CalculateY(530)),
            CPoint(CalculateX(284), CalculateY(537)),
            CPoint(CalculateX(headWidth / (2 * scale) + headOffsetX), CalculateY(510)),
            // 右侧顶点（镜像后）
            CPoint(MirrorX(284), CalculateY(537)),
            CPoint(MirrorX(200), CalculateY(530)),
            CPoint(MirrorX(215), CalculateY(345)),
            CPoint(CalculateX(215), CalculateY(345)) // 回到起点，封闭图形
        };

        int nPts = sizeof(bodyPts) / sizeof(CPoint);

        nullPen.CreateStockObject(NULL_PEN); // 创建空画笔（无轮廓）
        pDC->SelectObject(nullPen);
        pDC->SelectObject(&blueBrush);
        pDC->Polygon(bodyPts, nPts); // 直接填充多边形

        // 身体轮廓
        ptsLeftBodyCurve1[0] = CPoint(CalculateX(210), CalculateY(380));
        ptsLeftBodyCurve2[3] = CPoint(CalculateX(302), CalculateY(510));
        pDC->SelectObject(&headPen);
        pDC->MoveTo(ptsLeftBodyCurve1[0]);
        pDC->PolyBezierTo(ptsLeftBodyCurve1 + 1, 3);
        pDC->MoveTo(ptsLeftFootTop[0]);
        pDC->PolyBezierTo(ptsLeftFootTop + 1, 3);
        pDC->MoveTo(ptsLeftBodyCurve2[0]);
        pDC->PolyBezierTo(ptsLeftBodyCurve2 + 1, 3);
        for (int i = 0; i < 4; i++) {
            ptsRightBodyCurve2[i] = CPoint(MirrorXAbs(ptsLeftBodyCurve2[3 - i].x), ptsLeftBodyCurve2[3 - i].y);
        }
        pDC->MoveTo(ptsRightBodyCurve2[0]);
        pDC->PolyBezierTo(ptsRightBodyCurve2 + 1, 3);
        pDC->MoveTo(ptsRightFootTop[0]);
        pDC->PolyBezierTo(ptsRightFootTop + 1, 3);
        for (int i = 0; i < 4; i++) {
            ptsRightBodyCurve1[i] = CPoint(MirrorXAbs(ptsLeftBodyCurve1[3 - i].x), ptsLeftBodyCurve1[3 - i].y);
        }

        pDC->MoveTo(ptsRightBodyCurve1[0]);
        pDC->PolyBezierTo(ptsRightBodyCurve1 + 1, 3);

        // 白色肚皮
        pDC->SelectObject(&whiteBrush);

        CPoint belly[4];
        belly[0] = CPoint(CalculateX(240), CalculateY(350));
        belly[1] = CPoint(CalculateX(110), CalculateY(555));
        belly[2] = CPoint(MirrorXAbs(belly[1].x), belly[1].y);
        belly[3] = CPoint(MirrorXAbs(belly[0].x), belly[0].y);

        pDC->BeginPath();
        pDC->MoveTo(belly[0]);
        pDC->PolyBezierTo(belly + 1, 3);
        pDC->EndPath();
        pDC->StrokeAndFillPath();

        CPoint pocket[4];
        pocket[0] = CPoint(CalculateX(230), CalculateY(400));
        pocket[1] = CPoint(CalculateX(215), CalculateY(500));
        pocket[2] = CPoint(MirrorXAbs(pocket[1].x), pocket[1].y);
        pocket[3] = CPoint(MirrorXAbs(pocket[0].x), pocket[0].y);

        pDC->MoveTo(pocket[0]);
        pDC->PolyBezierTo(pocket + 1, 3);
        pDC->LineTo(pocket[0]);
        pDC->StrokePath();

        // 绘制红色围巾
        pDC->SelectObject(&scarfPen);
        pDC->SelectObject(&scarfBrush);

        // 围巾控制点
        CPoint ptsScarf[4];
        ptsScarf[0] = CPoint(CalculateX(220), CalculateY(330));
        ptsScarf[1] = CPoint(CalculateX(170), CalculateY(380));
        ptsScarf[2] = CPoint(CalculateX(430), CalculateY(380));
        ptsScarf[3] = CPoint(CalculateX(380), CalculateY(330));

        // 绘制围巾贝塞尔曲线
        pDC->BeginPath();
        pDC->MoveTo(ptsScarf[0]);
        pDC->PolyBezierTo(ptsScarf + 1, 3);
        pDC->LineTo(ptsScarf[0]);
        pDC->EndPath();
        pDC->StrokeAndFillPath();

        // 绘制贝塞尔曲线
        pDC->BeginPath();
        pDC->MoveTo(ptsScarf[0]);
        pDC->PolyBezierTo(ptsScarf + 1, 3);
        pDC->LineTo(ptsScarf[0]);            // 闭合路径
        pDC->EndPath();
        pDC->StrokeAndFillPath();       // 同时绘制轮廓和填充

        // 绘制铃铛
        // 铃铛轮廓
        pDC->SelectObject(&bellBrush);

        int bellX = (int)(270 * scale);
        int bellY = (int)(330 * scale);
        int bellWidth = (int)(60 * scale);
        int bellHeight = (int)(55 * scale);

        MyEllipse(pDC, CalculateX(270), CalculateY(330), CalculateX(330), CalculateY(385));

        // 铃铛中间的横杠
        pDC->SelectObject(&bellPen);
        pDC->MoveTo(CalculateX(273), CalculateY(343));
        pDC->LineTo(CalculateX(327), CalculateY(343));

        pDC->MoveTo(CalculateX(271), CalculateY(348));
        pDC->LineTo(CalculateX(329), CalculateY(348));

        // 铃铛中间的圆形
        pDC->SelectObject(&circleBrush);

        int circleX = bellX + (int)(25 * scale);
        int circleY = bellY + (int)(25 * scale);
        int circleSize = (int)(10 * scale);

        MyEllipse(pDC, CalculateX(295), CalculateY(355), CalculateX(305), CalculateY(365));

        // 铃铛下面的小垂直线
        pDC->MoveTo(CalculateX(300), CalculateY(365));
        pDC->LineTo(CalculateX(300), CalculateY(373));

        pDC->SelectObject(&whiteBrush);
        pDC->SelectObject(&headPen);

        int handLeftX = CalculateX(95);
        int handLeftY = CalculateY(415);
        int handRightX = CalculateX(165);
        int handRightY = CalculateY(485);

        // 左边手掌
        MyEllipse(pDC, handLeftX, handLeftY, handRightX, handRightY);

        // 右边手掌
        MyEllipse(pDC, MirrorXAbs(handLeftX), handLeftY, MirrorXAbs(handRightX), handRightY);

        // 恢复原来的画笔和画刷
        pDC->SelectObject(pOldPen);
        pDC->SelectObject(pOldBrush);
    }
}


// CDrawingBoard20220777View 打印

BOOL CDrawingBoard20220777View::OnPreparePrinting(CPrintInfo* pInfo)
{
    // 默认准备
    return DoPreparePrinting(pInfo);
}

void CDrawingBoard20220777View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    // TODO: 添加额外的打印前进行的初始化过程
}

void CDrawingBoard20220777View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
    // TODO: 添加打印后进行的清理过程
}


// CDrawingBoard20220777View 诊断

#ifdef _DEBUG
void CDrawingBoard20220777View::AssertValid() const
{
    CView::AssertValid();
}

void CDrawingBoard20220777View::Dump(CDumpContext& dc) const
{
    CView::Dump(dc);
}

CDrawingBoard20220777Doc* CDrawingBoard20220777View::GetDocument() const // 非调试版本是内联的
{
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDrawingBoard20220777Doc)));
    return (CDrawingBoard20220777Doc*)m_pDocument;
}
#endif //_DEBUG


// CDrawingBoard20220777View 消息处理程序

void CDrawingBoard20220777View::OnLButtonDown(UINT nFlags, CPoint point)
{
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    m_PointBegin = m_PointEnd = point;
    m_TextPos = point;
    m_MagnifyCenter = point;
    m_bDrawing = true;

    // 保存当前状态到撤销栈
    CRect rect;
    GetClientRect(&rect);

    CDC* pDC = GetDC();
    CDC memDC;
    memDC.CreateCompatibleDC(pDC);

    HBITMAP hBitmap = CreateCompatibleBitmap(pDC->GetSafeHdc(), rect.Width(), rect.Height());
    HBITMAP hOldBitmap = (HBITMAP)memDC.SelectObject(hBitmap);

    memDC.BitBlt(0, 0, rect.Width(), rect.Height(), &m_MemDC, 0, 0, SRCCOPY);

    memDC.SelectObject(hOldBitmap);
    m_UndoStack.push_back(hBitmap);
    ReleaseDC(pDC);

    switch (m_DrawType) {
    case DrawType::Magnify:
    {
        CClientDC dc(this);
        dc.SetROP2(R2_NOTXORPEN);

        CPen newPen, * oldPen;
        newPen.CreatePen(PS_SOLID, m_PenSize, m_PenColor);
        oldPen = dc.SelectObject(&newPen);
        dc.SelectStockObject(5);

        CRect* rectUndraw = GetMagnifyRect(m_MagnifyCenter);
        dc.Rectangle(rectUndraw);

        dc.SelectObject(oldPen);
        delete rectUndraw;

        break;
    }
    case DrawType::ColorPicker:
    {
        CClientDC dc(this);
        COLORREF color = dc.GetPixel(point);
        if (color != CLR_INVALID) {
            m_PenColor = color;
        }
        m_DrawType = DrawType::LineSegment;
        break;
    }
    case DrawType::WillowLeaf:
    {
        // 开始新的柳叶形轨迹
        m_WillowPoints.clear();
        m_WillowPoints.push_back(point);
        break;
    }
    case DrawType::Fill:  // 油漆桶工具
    {
        FloodFill(point);
        break;
    }
    }

    CView::OnLButtonDown(nFlags, point);
}

void CDrawingBoard20220777View::OnMouseMove(UINT nFlags, CPoint point)
{
    if (nFlags & MK_LBUTTON) {
        CClientDC dc(this);

        CPen newPen, * oldPen;
        newPen.CreatePen(PS_SOLID, m_PenSize, m_PenColor);
        oldPen = dc.SelectObject(&newPen);

        switch (m_DrawType) {
        case DrawType::LineSegment:
            dc.SetROP2(R2_NOTXORPEN);
            dc.MoveTo(m_PointBegin);
            dc.LineTo(m_PointEnd);
            dc.MoveTo(m_PointBegin);
            dc.LineTo(point);
            m_PointEnd = point;
            break;

        case DrawType::Rectangle:
        {
            dc.SetROP2(R2_NOTXORPEN);
            dc.SelectStockObject(NULL_BRUSH);
            CRect rectP1(m_PointBegin, m_PointEnd);
            dc.Rectangle(rectP1);
            CRect rectP2(m_PointBegin, point);
            dc.Rectangle(rectP2);
            m_PointEnd = point;
            break;
        }

        case DrawType::Circle:
        {
            dc.SetROP2(R2_NOTXORPEN);
            dc.SelectStockObject(NULL_BRUSH);

            int radiusOld = static_cast<int>(sqrt(
                pow(m_PointEnd.x - m_PointBegin.x, 2) +
                pow(m_PointEnd.y - m_PointBegin.y, 2)
            ));
            CRect rectOld(
                m_PointBegin.x - radiusOld,
                m_PointBegin.y - radiusOld,
                m_PointBegin.x + radiusOld,
                m_PointBegin.y + radiusOld
            );
            dc.Ellipse(rectOld);

            int radiusNew = static_cast<int>(sqrt(
                pow(point.x - m_PointBegin.x, 2) +
                pow(point.y - m_PointBegin.y, 2)
            ));
            CRect rectNew(
                m_PointBegin.x - radiusNew,
                m_PointBegin.y - radiusNew,
                m_PointBegin.x + radiusNew,
                m_PointBegin.y + radiusNew
            );
            dc.Ellipse(rectNew);

            m_PointEnd = point;
            break;
        }

        case DrawType::Ellips:
        {
            dc.SetROP2(R2_NOTXORPEN);
            dc.SelectStockObject(NULL_BRUSH);

            dc.Ellipse(CRect(m_PointBegin, m_PointEnd));
            dc.Ellipse(CRect(m_PointBegin, point));

            m_PointEnd = point;
            break;
        }
        case DrawType::Text:
        {

            // 仅绘制矩形预览，不创建编辑框
            dc.SetROP2(R2_NOTXORPEN);
            dc.SelectStockObject(NULL_BRUSH);

            // 擦除旧矩形
            dc.Rectangle(CRect(m_PointBegin, m_PointEnd));
            // 绘制新矩形
            dc.Rectangle(CRect(m_PointBegin, point));
            m_PointEnd = point;
            break;
        }
        case DrawType::Pencile:
        {
            m_PointBegin = m_PointEnd;
            m_PointEnd = point;
            dc.MoveTo(m_PointBegin);
            dc.LineTo(m_PointEnd);
            // 更新内存DC
            m_MemDC.MoveTo(m_PointBegin);
            m_MemDC.LineTo(m_PointEnd);
            break;
        }
        case DrawType::Eraser:
        {
            COLORREF pColor = this->m_BackgroundColor;
            CPen newPen(PS_SOLID, m_PenSize * 5, pColor);
            dc.SelectObject(&newPen);

            m_PointBegin = m_PointEnd;
            m_PointEnd = point;
            dc.MoveTo(m_PointBegin);
            dc.LineTo(m_PointEnd);
            // 更新内存DC
            m_MemDC.MoveTo(m_PointBegin);
            m_MemDC.LineTo(m_PointEnd);
            break;
        }
        case DrawType::Magnify:
        {
            dc.SetROP2(R2_NOTXORPEN);
            dc.SelectStockObject(5);

            CRect* rectUndraw = GetMagnifyRect(m_MagnifyCenter);
            dc.Rectangle(rectUndraw);
            delete rectUndraw;

            CRect* rectDraw = GetMagnifyRect(point);
            dc.Rectangle(rectDraw);
            delete rectDraw;

            m_MagnifyCenter = point;

            break;
        }
        case DrawType::Spray:
        {
            // 喷墨效果
            srand(static_cast<unsigned int>(time(nullptr)));
            for (int i = 0; i < m_SprayRadius * 1.5; i++) {
                int angle = rand() % 360;
                int distance = rand() % m_SprayRadius;
                int x = point.x + static_cast<int>(distance * cos(angle * 3.14159 / 180));
                int y = point.y + static_cast<int>(distance * sin(angle * 3.14159 / 180));

                dc.SetPixel(x, y, m_PenColor);
                m_MemDC.SetPixel(x, y, m_PenColor);
            }
            break;
        }
        case DrawType::RoundedRectangle: // 圆角矩形
        {
            dc.SetROP2(R2_NOTXORPEN);
            dc.SelectStockObject(NULL_BRUSH);

            // 擦除旧矩形
            DrawRoundedRectangle(dc, CRect(m_PointBegin, m_PointEnd), 10);
            // 绘制新矩形
            DrawRoundedRectangle(dc, CRect(m_PointBegin, point), 10);
            m_PointEnd = point;
            break;
        }

        case DrawType::Heart: // 爱心形
        {
            dc.SetROP2(R2_NOTXORPEN);
            dc.SelectStockObject(NULL_BRUSH);

            // 擦除旧爱心
            DrawHeart(dc, CRect(m_PointBegin, m_PointEnd));
            // 绘制新爱心
            DrawHeart(dc, CRect(m_PointBegin, point));
            m_PointEnd = point;
            break;
        }

        case DrawType::Star: // 星形
        {
            dc.SetROP2(R2_NOTXORPEN);
            dc.SelectStockObject(NULL_BRUSH);

            // 擦除旧星形
            DrawStar(dc, CRect(m_PointBegin, m_PointEnd), 5);
            // 绘制新星形
            DrawStar(dc, CRect(m_PointBegin, point), 5);
            m_PointEnd = point;
            break;
        }
        case DrawType::Hexagram: // 星形
        {
            dc.SetROP2(R2_NOTXORPEN);
            dc.SelectStockObject(NULL_BRUSH);

            // 擦除旧星形
            DrawHexagram(dc, CRect(m_PointBegin, m_PointEnd));
            // 绘制新星形
            DrawHexagram(dc, CRect(m_PointBegin, point));
            m_PointEnd = point;
            break;
        }
        case DrawType::UpArrow: // 上箭头
        case DrawType::DownArrow: // 下箭头
        case DrawType::LeftArrow: // 左箭头
        case DrawType::RightArrow: // 右箭头
        {
            dc.SetROP2(R2_NOTXORPEN);
            dc.SelectStockObject(NULL_BRUSH);

            // 擦除旧箭头
            DrawArrow(dc, CRect(m_PointBegin, m_PointEnd), m_DrawType);
            // 绘制新箭头
            DrawArrow(dc, CRect(m_PointBegin, point), m_DrawType);
            m_PointEnd = point;
            break;
        }

        case DrawType::Cloud: // 云形
        {
            dc.SetROP2(R2_NOTXORPEN);
            dc.SelectStockObject(NULL_BRUSH);

            // 擦除旧云形
            DrawCloud(dc, CRect(m_PointBegin, m_PointEnd));
            // 绘制新云形
            DrawCloud(dc, CRect(m_PointBegin, point));
            m_PointEnd = point;
            break;
        }

        case DrawType::Wave: // 波浪线
        {
            dc.SetROP2(R2_NOTXORPEN);

            // 擦除旧波浪线
            DrawWave(dc, m_PointBegin, m_PointEnd, 10, 30);
            // 绘制新波浪线
            DrawWave(dc, m_PointBegin, point, 10, 30);
            m_PointEnd = point;
            break;
        }

        case DrawType::WillowLeaf:
        {
            if (m_bDrawing) {
                // 添加点到轨迹
                m_WillowPoints.push_back(point);

                // 绘制实时预览
                CClientDC dc(this);
                CPen newPen(PS_SOLID, m_PenSize, m_PenColor);
                CPen* oldPen = dc.SelectObject(&newPen);

                // 绘制平滑曲线
                if (m_WillowPoints.size() > 1) {
                    dc.MoveTo(m_WillowPoints[0]);
                    for (size_t i = 1; i < m_WillowPoints.size(); i++) {
                        // 使用LineTo直接连接点
                        dc.LineTo(m_WillowPoints[i]);
                    }
                }

                dc.SelectObject(oldPen);
            }
            break;
        }

        case DrawType::Diamond: // 菱形
        {
            dc.SetROP2(R2_NOTXORPEN);
            dc.SelectStockObject(NULL_BRUSH);

            // 擦除旧菱形
            DrawDiamond(dc, CRect(m_PointBegin, m_PointEnd));
            // 绘制新菱形
            DrawDiamond(dc, CRect(m_PointBegin, point));
            m_PointEnd = point;
            break;
        }

        case DrawType::Hexagon: // 六边形
        {
            dc.SetROP2(R2_NOTXORPEN);
            dc.SelectStockObject(NULL_BRUSH);

            // 擦除旧六边形
            DrawHexagon(dc, CRect(m_PointBegin, m_PointEnd));
            // 绘制新六边形
            DrawHexagon(dc, CRect(m_PointBegin, point));
            m_PointEnd = point;
            break;
        }

        case DrawType::Pentagon: // 五边形
        {
            dc.SetROP2(R2_NOTXORPEN);
            dc.SelectStockObject(NULL_BRUSH);

            // 擦除旧五边形
            DrawPentagon(dc, CRect(m_PointBegin, m_PointEnd));
            // 绘制新五边形
            DrawPentagon(dc, CRect(m_PointBegin, point));
            m_PointEnd = point;
            break;
        }

        case DrawType::bomb: // 炸弹
        {
            dc.SetROP2(R2_NOTXORPEN);
            dc.SelectStockObject(NULL_BRUSH);

            // 擦除旧炸弹
            Drawbomb(dc, CRect(m_PointBegin, m_PointEnd));
            // 绘制新炸弹
            Drawbomb(dc, CRect(m_PointBegin, point));
            m_PointEnd = point;
            break;
        }
        default:
            break;
        }

        dc.SelectObject(oldPen);
    }

    CView::OnMouseMove(nFlags, point);
}

void CDrawingBoard20220777View::OnLButtonUp(UINT nFlags, CPoint point)
{
    CClientDC dc(this);

    CPen newPen, * oldPen;
    newPen.CreatePen(PS_SOLID, m_PenSize, m_PenColor);
    oldPen = dc.SelectObject(&newPen);

    switch (m_DrawType) {
    case DrawType::LineSegment:
        dc.MoveTo(m_PointBegin);
        dc.LineTo(m_PointEnd);
        // 更新内存DC
        m_MemDC.MoveTo(m_PointBegin);
        m_MemDC.LineTo(m_PointEnd);
        break;

    case DrawType::Rectangle:
        dc.SelectStockObject(NULL_BRUSH);
        dc.Rectangle(CRect(m_PointBegin, point));
        // 更新内存DC
        m_MemDC.Rectangle(CRect(m_PointBegin, point));
        break;

    case DrawType::Circle:
    {
        dc.SelectStockObject(NULL_BRUSH);

        int radius = static_cast<int>(sqrt(
            pow(point.x - m_PointBegin.x, 2) +
            pow(point.y - m_PointBegin.y, 2)
        ));

        CRect circleRect(
            m_PointBegin.x - radius,
            m_PointBegin.y - radius,
            m_PointBegin.x + radius,
            m_PointBegin.y + radius
        );
        dc.Ellipse(circleRect);
        // 更新内存DC
        m_MemDC.Ellipse(circleRect);
        break;
    }

    case DrawType::Ellips:
        dc.SelectStockObject(NULL_BRUSH);
        dc.Ellipse(CRect(m_PointBegin, point));
        // 更新内存DC
        m_MemDC.Ellipse(CRect(m_PointBegin, point));
        break;

    case DrawType::Text:
    {
        // 擦除预览矩形
        dc.SetROP2(R2_NOTXORPEN);
        dc.SelectStockObject(NULL_BRUSH);
        dc.Rectangle(CRect(m_PointBegin, m_PointEnd));

        // 确保矩形有效
        CRect textRect(m_PointBegin, point);
        textRect.NormalizeRect();
        if (textRect.Width() < 10) textRect.right = textRect.left + 100;
        if (textRect.Height() < 10) textRect.bottom = textRect.top + 20;

        // 删除旧编辑框
        if (m_Edit) {
            delete m_Edit;
            m_Edit = nullptr;
        }

        // 创建新编辑框
        m_Edit = new CEdit();
        m_Edit->Create(WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | ES_AUTOVSCROLL,
            textRect, this, m_TextId);
        // 设置字体并获取焦点
        if (m_TextFont.GetSafeHandle() != NULL) {
            m_Edit->SetFont(&m_TextFont);
        }
        m_Edit->SetFocus();
        break;
    }
    case DrawType::Magnify:
    {
        dc.SetROP2(R2_NOTXORPEN);
        dc.SelectStockObject(5);

        CRect* rectUndraw = GetMagnifyRect(m_MagnifyCenter);
        dc.Rectangle(rectUndraw);

        CRect rect;
        GetClientRect(&rect);

        CDC* pDC = GetDC();
        dc.StretchBlt(0, 0, rect.Width(), rect.Height(), pDC, rectUndraw->left, rectUndraw->top, rectUndraw->Width(), rectUndraw->Height(), SRCCOPY);

        delete rectUndraw;
        ReleaseDC(pDC);

        break;
    }
    case DrawType::RoundedRectangle: // 圆角矩形
        DrawRoundedRectangle(dc, CRect(m_PointBegin, point), 10);
        DrawRoundedRectangle(m_MemDC, CRect(m_PointBegin, point), 10);
        break;

    case DrawType::Heart: // 爱心形
        DrawHeart(dc, CRect(m_PointBegin, point));
        DrawHeart(m_MemDC, CRect(m_PointBegin, point));
        break;

    case DrawType::Star: // 星形
        DrawStar(dc, CRect(m_PointBegin, point), 5);
        DrawStar(m_MemDC, CRect(m_PointBegin, point), 5);
        break;
    case DrawType::Hexagram: // 星形
        DrawHexagram(dc, CRect(m_PointBegin, point));
        DrawHexagram(m_MemDC, CRect(m_PointBegin, point));
        break;
    case DrawType::UpArrow: // 上箭头
    case DrawType::DownArrow: // 下箭头
    case DrawType::LeftArrow: // 左箭头
    case DrawType::RightArrow: // 右箭头
        DrawArrow(dc, CRect(m_PointBegin, point), m_DrawType);
        DrawArrow(m_MemDC, CRect(m_PointBegin, point), m_DrawType);
        break;

    case DrawType::Cloud: // 云形
        DrawCloud(dc, CRect(m_PointBegin, point));
        DrawCloud(m_MemDC, CRect(m_PointBegin, point));
        break;

    case DrawType::Wave: // 波浪线
        DrawWave(dc, m_PointBegin, point, 10, 30);
        DrawWave(m_MemDC, m_PointBegin, point, 10, 30);
        break;

    case DrawType::WillowLeaf:
    {
        if (m_WillowPoints.size() > 1) {
            // 闭合曲线（连接首尾点）
            if (m_WillowPoints.front() != m_WillowPoints.back()) {
                m_WillowPoints.push_back(m_WillowPoints.front());
            }
            
            // 创建柳叶形路径
            CClientDC dc(this);
            CPen newPen(PS_SOLID, m_PenSize, m_PenColor);
            CPen* oldPen = dc.SelectObject(&newPen);
            
            // 创建路径
            dc.BeginPath();
            dc.MoveTo(m_WillowPoints[0]);
            
            for (size_t i = 1; i < m_WillowPoints.size(); i++) {
                dc.LineTo(m_WillowPoints[i]);
            }
            
            dc.CloseFigure();
            dc.EndPath();
            
            // 填充路径
            CBrush brush(m_PenColor);
            CBrush* oldBrush = dc.SelectObject(&brush);
            dc.StrokeAndFillPath();
            dc.SelectObject(oldBrush);
            
            // 保存到内存DC
            CDC* pMemDC = &m_MemDC;
            pMemDC->SelectObject(&newPen);
            pMemDC->BeginPath();
            pMemDC->MoveTo(m_WillowPoints[0]);
            
            for (size_t i = 1; i < m_WillowPoints.size(); i++) {
                pMemDC->LineTo(m_WillowPoints[i]);
            }
            
            pMemDC->CloseFigure();
            pMemDC->EndPath();
            
            CBrush memBrush(m_PenColor);
            CBrush* oldMemBrush = pMemDC->SelectObject(&memBrush);
            pMemDC->StrokeAndFillPath();
            pMemDC->SelectObject(oldMemBrush);
            
            dc.SelectObject(oldPen);
        }
        
        // 清空轨迹点
        m_WillowPoints.clear();
        break;
    }

    case DrawType::Diamond: // 菱形
        DrawDiamond(dc, CRect(m_PointBegin, point));
        DrawDiamond(m_MemDC, CRect(m_PointBegin, point));
        break;

    case DrawType::Hexagon: // 六边形
        DrawHexagon(dc, CRect(m_PointBegin, point));
        DrawHexagon(m_MemDC, CRect(m_PointBegin, point));
        break;

    case DrawType::Pentagon: // 五边形
        DrawPentagon(dc, CRect(m_PointBegin, point));
        DrawPentagon(m_MemDC, CRect(m_PointBegin, point));
        break;

    case DrawType::bomb: // 炸弹
        Drawbomb(dc, CRect(m_PointBegin, point));
        Drawbomb(m_MemDC, CRect(m_PointBegin, point));
        break;

    default:
        break;
    }
    dc.SelectObject(oldPen);
    m_bDrawing = false;

    CView::OnLButtonUp(nFlags, point);
}





void CDrawingBoard20220777View::OnLine()
{
    m_DrawType = DrawType::LineSegment;
    // TODO: 在此添加命令处理程序代码

}

void CDrawingBoard20220777View::OnRectangle()
{
    m_DrawType = DrawType::Rectangle;
    // TODO: 在此添加命令处理程序代码
}

void CDrawingBoard20220777View::OnCircle()
{
    m_DrawType = DrawType::Circle;
    // TODO: 在此添加命令处理程序代码
}

void CDrawingBoard20220777View::OnEllipse()
{
    // TODO: 在此添加命令处理程序代码
    m_DrawType = DrawType::Ellips;
}

void CDrawingBoard20220777View::OnSetColor()
{
    // TODO: 在此添加命令处理程序代码
    CColorDialog dlg;
    if (IDOK == dlg.DoModal()) {
        m_PenColor = dlg.GetColor();
    }
}

void CDrawingBoard20220777View::SetTextFont(CFont* pFont)  
{  
    if (pFont)  
    {  
        LOGFONT logFont;  
        if (pFont->GetLogFont(&logFont)) // Retrieve the LOGFONT structure from the CFont object  
        {  
            m_TextFont.DeleteObject();
            m_TextFont.CreateFontIndirect(&logFont); // Pass the LOGFONT structure to CreateFontIndirect  
        }  
    }  
}
void CDrawingBoard20220777View::OnSetPenSize()
{
    // TODO: 在此添加命令处理程序代码
    setSize dlg;
    if (IDOK == dlg.DoModal()) {
        this->m_PenSize = dlg.m_PenSize;
        this->m_SprayRadius = dlg.m_PenSize * 20;

    }
}

BOOL CDrawingBoard20220777View::PreTranslateMessage(MSG* pMsg)
{
    // 处理文本输入相关的消息
    if (m_Edit && ::IsWindow(m_Edit->m_hWnd))
    {
        // 处理Shift+Enter组合键保存文本
        if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN)
        {
            // 检查Shift键状态
            bool shiftPressed = (GetKeyState(VK_SHIFT) & 0x8000) != 0;

            if (shiftPressed)
            {
                SaveTextToCanvas(); // 保存文本到画布
                RemoveTextEdit();   // 移除编辑框
                return TRUE;        // 已处理消息
            }
            else
            {
                // 普通Enter：插入换行符
                return FALSE; // 让编辑框处理普通Enter键
            }
        }
        // 处理ESC键取消文本输入
        else if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
        {
            RemoveTextEdit(false); // 移除编辑框，不保存文本
            return TRUE;           // 已处理消息
        }
        // 处理失去焦点事件
        else if (pMsg->message == WM_KILLFOCUS && pMsg->hwnd == m_Edit->m_hWnd)
        {
            SaveTextToCanvas(); // 保存文本到画布
            RemoveTextEdit();   // 移除编辑框
            return TRUE;        // 已处理消息
        }
    }

    return CView::PreTranslateMessage(pMsg);
}
// 保存文本到画布
// 修改文字绘制函数，在绘制前保存当前状态到撤销栈
void CDrawingBoard20220777View::SaveTextToCanvas()
{
    if (m_Edit && ::IsWindow(m_Edit->m_hWnd))
    {
        CString text;
        m_Edit->GetWindowText(text);

        if (!text.IsEmpty())
        {
            // 保存当前状态到撤销栈（保持原有逻辑）
            CRect rect;
            GetClientRect(&rect);

            CBitmap bitmap;
            bitmap.CreateCompatibleBitmap(&m_MemDC, rect.Width(), rect.Height());

            CDC memDC;
            memDC.CreateCompatibleDC(&m_MemDC);
            HBITMAP hOldBitmap = (HBITMAP)memDC.SelectObject(bitmap);

            memDC.BitBlt(0, 0, rect.Width(), rect.Height(), &m_MemDC, 0, 0, SRCCOPY);
            m_UndoStack.push_back((HBITMAP)CopyImage(bitmap, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG));
            memDC.SelectObject(hOldBitmap);

            // 获取编辑框位置
            CRect editRect;
            m_Edit->GetWindowRect(&editRect);
            ScreenToClient(&editRect);

            // 使用DrawText替代TextOut，支持多行文本
            CFont* pOldFont = m_MemDC.SelectObject(&m_TextFont);
            COLORREF oldColor = m_MemDC.SetTextColor(m_TextColor);
            int oldBkMode = m_MemDC.SetBkMode(TRANSPARENT);

            // 计算文本显示区域
            CRect textRect = editRect;
            textRect.bottom = rect.bottom; // 确保有足够空间显示所有行

            // 使用DrawText绘制多行文本
            m_MemDC.DrawText(text, textRect, DT_LEFT | DT_TOP | DT_WORDBREAK);

            // 恢复DC设置
            m_MemDC.SetBkMode(oldBkMode);
            m_MemDC.SetTextColor(oldColor);
            m_MemDC.SelectObject(pOldFont);
        }
    }
}

// 移除文本编辑框
void CDrawingBoard20220777View::RemoveTextEdit(bool saveText)
{
    if (m_Edit && ::IsWindow(m_Edit->m_hWnd))
    {
        // 保存文本（如果需要）
        if (saveText) {
            SaveTextToCanvas();
        }

        // 获取编辑框位置用于重绘
        CRect editRect;
        m_Edit->GetWindowRect(&editRect);
        ScreenToClient(&editRect);

        // 删除编辑框
        m_Edit->DestroyWindow();
        delete m_Edit;
        m_Edit = nullptr;

        // 重置绘图状态
        m_DrawType = DrawType::None;

        // 重绘视图
        InvalidateRect(&editRect);
    }
}

void CDrawingBoard20220777View::OnSetPencil()
{
    // TODO: 在此添加命令处理程序代码
    m_DrawType = DrawType::Pencile;
}

void CDrawingBoard20220777View::OnSetEraser()
{
    // TODO: 在此添加命令处理程序代码
    m_DrawType = DrawType::Eraser;
}

void CDrawingBoard20220777View::OnFileOpen()
{


    // 定义文件筛选器和路径变量
    m_DrawType = DrawType::myLoadImage;
    CString filter, strPath;
    filter = _T("bmp图片(*.bmp)|*.bmp||");
    CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, filter);

    // 显示文件对话框并获取用户选择
    if (dlg.DoModal() == IDOK)
    {
        strPath = dlg.GetPathName();
    }
    else
    {
        return; // 用户取消选择，直接返回
    }

    // 使用 CImage 加载图片（替代 LoadImage，兼容性更好）
    CImage img;
    HRESULT hr = img.Load(strPath);
    if (FAILED(hr))
    {
        CString errMsg;
        errMsg.Format(_T("图片加载失败！\n错误代码: 0x%08X\n路径: %s"), hr, strPath);
        AfxMessageBox(errMsg, MB_ICONERROR);
        return;
    }

    // 检查图片尺寸是否有效
    int width = img.GetWidth();
    int height = img.GetHeight();
    if (width <= 0 || height <= 0)
    {
        AfxMessageBox(_T("图片尺寸无效！"), MB_ICONERROR);
        return;
    }
    // 保存当前状态到撤销栈（保持原有逻辑）
    CRect rect;
    GetClientRect(&rect);

    CBitmap bitmap;
    bitmap.CreateCompatibleBitmap(&m_MemDC, rect.Width(), rect.Height());

    CDC memDC;
    memDC.CreateCompatibleDC(&m_MemDC);
    HBITMAP hOldBitmap = (HBITMAP)memDC.SelectObject(bitmap);

    memDC.BitBlt(0, 0, rect.Width(), rect.Height(), &m_MemDC, 0, 0, SRCCOPY);
    m_UndoStack.push_back((HBITMAP)CopyImage(bitmap, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG));
    memDC.SelectObject(hOldBitmap);

    // 显示图片尺寸信息（调试用）
    CString sizeInfo;
    sizeInfo.Format(_T("图片尺寸: %dx%d 像素"), width, height);
    TRACE(sizeInfo + _T("\n"));

    // 确保窗口已更新（避免绘制异常）
    UpdateWindow();

    // 获取设备上下文并绘制图片
    CClientDC dc(this);
    CRect clientRect;
    GetClientRect(&clientRect);

    // 计算居中显示的位置
    int x = (clientRect.Width() - width) / 2;
    int y = (clientRect.Height() - height) / 2;

    // 使用 StretchBlt 绘制图片（支持缩放）
    img.StretchBlt(
        dc.GetSafeHdc(),
        x, y, width, height,
        0, 0, width, height,
        SRCCOPY
    );

    // 更新内存DC
    img.StretchBlt(
        m_MemDC.GetSafeHdc(),
        x, y, width, height,
        0, 0, width, height,
        SRCCOPY
    );

    // 可选：保存图片句柄用于后续清理（如果需要）
    // m_hCurrentBitmap = img.Detach();
}

void CDrawingBoard20220777View::OnText()
{
    // 创建字体对话框
    CFontDialog fontDlg;

    // 设置初始字体属性
    LOGFONT lf;
    m_TextFont.GetLogFont(&lf);
    fontDlg.m_cf.lpLogFont = &lf;
    fontDlg.m_cf.rgbColors = m_TextColor;
    fontDlg.m_cf.Flags |= CF_EFFECTS | CF_INITTOLOGFONTSTRUCT;

    // 显示字体对话框
    if (fontDlg.DoModal() == IDOK)
    {
        // 更新字体
        if (m_TextFont.GetSafeHandle() != NULL)
            m_TextFont.DeleteObject();

        m_TextFont.CreateFontIndirect(&lf);
        m_TextColor = fontDlg.GetColor();

        // 计算字体大小（点）
        CDC* pDC = GetDC();
        int height = -MulDiv(lf.lfHeight, 72, GetDeviceCaps(pDC->m_hDC, LOGPIXELSY));
        ReleaseDC(pDC);
        m_TextSize = abs(height);

        // 设置绘图类型为文本
        m_DrawType = DrawType::Text;
    }
}

// 设置背景颜色
void CDrawingBoard20220777View::OnSetBackgroundColor()
{
    CColorDialog colorDlg(m_BackgroundColor, CC_FULLOPEN, this);

    if (colorDlg.DoModal() == IDOK)
    {
        this->m_BackgroundColor = colorDlg.GetColor();
        // 更新背景画刷
        m_BackgroundBrush.DeleteObject();
        m_BackgroundBrush.CreateSolidBrush(m_BackgroundColor);

        // 不需要在此填充内存DC，由OnEraseBkgnd统一处理
        RedrawAllToMemoryDC(); // 重绘内容到内存DC

        // 强制整个窗口重绘
        Invalidate(TRUE); // TRUE表示擦除背景（会触发OnEraseBkgnd）
    }
}

BOOL CDrawingBoard20220777View::OnEraseBkgnd(CDC* pDC)
{
    CRect rect;
    GetClientRect(&rect);
    pDC->FillRect(&rect, &m_BackgroundBrush); // 使用背景画刷填充整个窗口
    return TRUE; // 已处理背景擦除
}


// 重绘所有内容到内存DC
void CDrawingBoard20220777View::RedrawAllToMemoryDC()
{
    // 获取客户区大小
    CRect rect;
    GetClientRect(&rect);

    // 清除内存DC
    m_MemDC.FillRect(&rect, &m_BackgroundBrush);

    // 重新绘制所有组件
    // 无
}
void CDrawingBoard20220777View::OnMagnify()
{
    // TODO: 在此添加命令处理程序代码
    m_DrawType = DrawType::Magnify;
}

CRect* CDrawingBoard20220777View::GetMagnifyRect(CPoint& p_Msg)
{
    CRect rect;
    GetClientRect(&rect);

    CPoint leftTop, rightBottom;
    leftTop.x = p_Msg.x - m_MagnifyWidth / 2;
    rightBottom.x = p_Msg.x + m_MagnifyWidth / 2;
    leftTop.y = p_Msg.y - m_MagnifyHeight / 2;
    rightBottom.y = p_Msg.y + m_MagnifyHeight / 2;

    if (leftTop.x < 0) {
        leftTop.x = 0;
        rightBottom.x = leftTop.x + m_MagnifyWidth;
    }
    else if (rightBottom.x > rect.right) {
        rightBottom.x = rect.right;
        leftTop.x = rightBottom.x - m_MagnifyWidth;
    }

    if (leftTop.y < 0) {
        leftTop.y = 0;
        rightBottom.y = leftTop.y + m_MagnifyHeight;
    }
    else if (rightBottom.y > rect.bottom) {
        rightBottom.y = rect.bottom;
        leftTop.y = rightBottom.y - m_MagnifyHeight;
    }

    CRect* r_Rect = new CRect(leftTop, rightBottom);

    return r_Rect;
}

void CDrawingBoard20220777View::OnUndo()
{
    // 撤销功能
    if (!m_UndoStack.empty())
    {
        // 获取最后保存的状态
        HBITMAP hLastBitmap = m_UndoStack.back();
        m_UndoStack.pop_back();

        // 创建临时内存DC用于操作撤销的位图
        CDC tempDC;
        tempDC.CreateCompatibleDC(nullptr);
        HBITMAP hOldTempBitmap = (HBITMAP)tempDC.SelectObject(hLastBitmap);

        // 获取视图尺寸
        CRect rect;
        GetClientRect(&rect);

        // 创建一个新的位图用于m_MemDC
        CBitmap newBitmap;
        newBitmap.CreateCompatibleBitmap(&tempDC, rect.Width(), rect.Height());

        // 保存当前m_MemDC的位图
        HBITMAP hOldMemBitmap = (HBITMAP)m_MemDC.SelectObject(&newBitmap);

        // 将撤销的内容复制到新的m_MemDC位图
        m_MemDC.BitBlt(0, 0, rect.Width(), rect.Height(), &tempDC, 0, 0, SRCCOPY);

        // 恢复m_MemDC的原始位图并删除它(现在它已经被撤销)
        m_MemDC.SelectObject(hOldMemBitmap);
        DeleteObject(hOldMemBitmap);

        // 清理临时DC
        tempDC.SelectObject(hOldTempBitmap);
        DeleteObject(hLastBitmap);

        // 重绘视图
        Invalidate();
    }
}

void CDrawingBoard20220777View::OnReload()
{
    // 重新加载（清空画布）
    CRect rect;
    GetClientRect(&rect);
    m_MemDC.FillSolidRect(rect, RGB(255, 255, 255)); // 白色背景

    // 清空撤销栈
    for (auto hBitmap : m_UndoStack) {
        if (hBitmap != nullptr) {
            DeleteObject(hBitmap);
        }
    }
    m_UndoStack.clear();

    Invalidate(); // 重绘视图
}

void CDrawingBoard20220777View::OnSpray()
{
    // 喷墨工具
    m_DrawType = DrawType::Spray;
}

void CDrawingBoard20220777View::OnColorPicker()
{
    // 颜色提取工具
    m_DrawType = DrawType::ColorPicker;
}


void CDrawingBoard20220777View::DrawRoundedRectangle(CDC& dc, CRect rect, int cornerRadiusFactor)
{
    rect.NormalizeRect();

    // 圆角半径随矩形大小变化（取宽高的最小值的1/6）
    int minSize = min(rect.Width(), rect.Height());
    int cornerRadius = minSize / cornerRadiusFactor;

    // 保存当前画刷状态
    CBrush* pOldBrush = nullptr;
    CBrush* pNullBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));

    // 选择空画刷以确保不填充
    pOldBrush = dc.SelectObject(pNullBrush);

    // 绘制圆角矩形轮廓（使用当前画笔颜色）
    dc.RoundRect(rect, CPoint(cornerRadius, cornerRadius));

    // 恢复之前的画刷
    if (pOldBrush)
    {
        dc.SelectObject(pOldBrush);
    }
}
void CDrawingBoard20220777View::DrawHeart(CDC& dc, CRect rect)
{
    rect.NormalizeRect();
    CPoint center = rect.CenterPoint();
    int width = rect.Width() / 2;
    int height = rect.Height() / 2;

    // 使用爱心参数方程绘制
    dc.BeginPath();
    const int steps = 100;
    double scale = min(width, height) / 1.5;

    for (int i = 0; i <= steps; i++)
    {
        double t = 2 * M_PI * i / steps;
        // 爱心参数方程
        double x = 16 * pow(sin(t), 3);
        double y = 13 * cos(t) - 5 * cos(2 * t) - 2 * cos(3 * t) - cos(4 * t);

        // 缩放并移动到中心
        int px = center.x + (int)(x * scale / 16);
        int py = center.y - (int)(y * scale / 16); // 注意Y轴方向

        if (i == 0)
            dc.MoveTo(px, py);
        else
            dc.LineTo(px, py);
    }

    dc.CloseFigure();
    dc.EndPath();

    // 仅描边，不填充
    dc.StrokePath();
}
// 绘制六角星形
void CDrawingBoard20220777View::DrawHexagram(CDC& dc, CRect rect)
{
    rect.NormalizeRect();
    CPoint center = rect.CenterPoint();
    int radius = min(rect.Width(), rect.Height()) / 2;

    // 创建并初始化点数组（两个三角形，共6个点）
    POINT* starPoints = new POINT[6];

    // 上方三角形
    starPoints[0].x = center.x;               starPoints[0].y = center.y - radius;     // 顶部点
    starPoints[1].x = center.x - radius / 2;  starPoints[1].y = center.y + radius / 2; // 左下点
    starPoints[2].x = center.x + radius / 2;  starPoints[2].y = center.y + radius / 2; // 右下点

    // 下方三角形
    starPoints[3].x = center.x - radius / 2;  starPoints[3].y = center.y - radius / 2; // 左上点
    starPoints[4].x = center.x + radius / 2;  starPoints[4].y = center.y - radius / 2; // 右上点
    starPoints[5].x = center.x;               starPoints[5].y = center.y + radius;     // 底部点

    // 绘制第一个三角形
    dc.MoveTo(starPoints[0]);
    dc.LineTo(starPoints[1]);
    dc.LineTo(starPoints[2]);
    dc.LineTo(starPoints[0]); // 闭合第一个三角形

    // 绘制第二个三角形
    dc.MoveTo(starPoints[3]);
    dc.LineTo(starPoints[4]);
    dc.LineTo(starPoints[5]);
    dc.LineTo(starPoints[3]); // 闭合第二个三角形

    // 释放资源
    delete[] starPoints;
}

// 绘制星形
void CDrawingBoard20220777View::DrawStar(CDC& dc, CRect rect, int points)
{

    rect.NormalizeRect();
    CPoint center = rect.CenterPoint();
    int radius = min(rect.Width(), rect.Height()) / 2;

    // 创建并初始化点数组
    POINT* starPoints = new POINT[points * 2];
    double angle = -M_PI / 2;
    double angleIncrement = M_PI / points;

    for (int i = 0; i < points * 2; i++)
    {
        int r = (i % 2 == 0) ? radius : radius / 2;
        starPoints[i].x = center.x + (int)(r * cos(angle));
        starPoints[i].y = center.y + (int)(r * sin(angle));
        angle += angleIncrement;
    }

    // 绘制星星轮廓（使用当前画笔颜色）
    dc.Polyline(starPoints, points * 2);

    // 闭合路径 (从最后一点连接到第一点)
    dc.MoveTo(starPoints[0]);
    dc.LineTo(starPoints[points * 2 - 1]);

    // 释放资源
    delete[] starPoints;
}

void CDrawingBoard20220777View::DrawArrow(CDC& dc, CRect rect, DrawType arrowType)
{
    rect.NormalizeRect();
    double arrowHeadRatio = 0.3; // 箭头头部占总长的比例

    // 保存当前画刷状态
    CBrush* pOldBrush = nullptr;
    CBrush* pNullBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
    pOldBrush = dc.SelectObject(pNullBrush);

    switch (arrowType)
    {
    case DrawType::UpArrow:
    {
        int shaftWidth = rect.Width() / 3;
        int shaftHeight = rect.Height() * (1 - arrowHeadRatio);

        // 绘制箭杆（矩形轮廓）
        CRect shaftRect(
            rect.CenterPoint().x - shaftWidth / 2,
            rect.top + rect.Height() * arrowHeadRatio,
            rect.CenterPoint().x + shaftWidth / 2,
            rect.bottom
        );
        dc.Rectangle(shaftRect);

        // 绘制箭头（等腰三角形轮廓）
        POINT arrowPoints[3] = {
            {rect.CenterPoint().x, rect.top}, // 顶点
            {rect.CenterPoint().x - shaftWidth, rect.top + rect.Height() * arrowHeadRatio}, // 左底点
            {rect.CenterPoint().x + shaftWidth, rect.top + rect.Height() * arrowHeadRatio}  // 右底点
        };
        dc.Polyline(arrowPoints, 3);
        dc.MoveTo(arrowPoints[0]);
        dc.LineTo(arrowPoints[2]); // 闭合三角形
        break;
    }

    case DrawType::DownArrow:
    {
        int shaftWidth = rect.Width() / 3;
        int shaftHeight = rect.Height() * (1 - arrowHeadRatio);

        // 绘制箭杆（矩形轮廓）
        CRect shaftRect(
            rect.CenterPoint().x - shaftWidth / 2,
            rect.top,
            rect.CenterPoint().x + shaftWidth / 2,
            rect.bottom - rect.Height() * arrowHeadRatio
        );
        dc.Rectangle(shaftRect);

        // 绘制箭头（等腰三角形轮廓）
        POINT arrowPoints[3] = {
            {rect.CenterPoint().x, rect.bottom}, // 顶点
            {rect.CenterPoint().x - shaftWidth, rect.bottom - rect.Height() * arrowHeadRatio}, // 左顶点
            {rect.CenterPoint().x + shaftWidth, rect.bottom - rect.Height() * arrowHeadRatio}  // 右顶点
        };
        dc.Polyline(arrowPoints, 3);
        dc.MoveTo(arrowPoints[0]);
        dc.LineTo(arrowPoints[2]); // 闭合三角形
        break;
    }

    case DrawType::LeftArrow:
    {
        int shaftWidth = rect.Width() * (1 - arrowHeadRatio);
        int shaftHeight = rect.Height() / 3;

        // 绘制箭杆（矩形轮廓）
        CRect shaftRect(
            rect.left + rect.Width() * arrowHeadRatio,
            rect.CenterPoint().y - shaftHeight / 2,
            rect.right,
            rect.CenterPoint().y + shaftHeight / 2
        );
        dc.Rectangle(shaftRect);

        // 绘制箭头（等腰三角形轮廓）
        POINT arrowPoints[3] = {
            {rect.left, rect.CenterPoint().y}, // 顶点
            {rect.left + rect.Width() * arrowHeadRatio, rect.CenterPoint().y - shaftHeight}, // 上底点
            {rect.left + rect.Width() * arrowHeadRatio, rect.CenterPoint().y + shaftHeight}  // 下底点
        };
        dc.Polyline(arrowPoints, 3);
        dc.MoveTo(arrowPoints[0]);
        dc.LineTo(arrowPoints[2]); // 闭合三角形
        break;
    }

    case DrawType::RightArrow:
    {
        int shaftWidth = rect.Width() * (1 - arrowHeadRatio);
        int shaftHeight = rect.Height() / 3;

        // 绘制箭杆（矩形轮廓）
        CRect shaftRect(
            rect.left,
            rect.CenterPoint().y - shaftHeight / 2,
            rect.right - rect.Width() * arrowHeadRatio,
            rect.CenterPoint().y + shaftHeight / 2
        );
        dc.Rectangle(shaftRect);

        // 绘制箭头（等腰三角形轮廓）
        POINT arrowPoints[3] = {
            {rect.right, rect.CenterPoint().y}, // 顶点
            {rect.right - rect.Width() * arrowHeadRatio, rect.CenterPoint().y - shaftHeight}, // 上底点
            {rect.right - rect.Width() * arrowHeadRatio, rect.CenterPoint().y + shaftHeight}  // 下底点
        };
        dc.Polyline(arrowPoints, 3);
        dc.MoveTo(arrowPoints[0]);
        dc.LineTo(arrowPoints[2]); // 闭合三角形
        break;
    }
    }

    // 恢复之前的画刷
    if (pOldBrush)
    {
        dc.SelectObject(pOldBrush);
    }
}

void CDrawingBoard20220777View::DrawCloud(CDC& dc, CRect rect)
{
    rect.NormalizeRect();
    int centerX = rect.CenterPoint().x;
    int centerY = rect.CenterPoint().y;
    int width = rect.Width() / 2;
    int height = rect.Height() / 2;

    // 使用贝塞尔曲线绘制云形
    CPoint points[13];

    // 云形轮廓点
    points[0] = CPoint(centerX - width * 0.7, centerY);
    points[1] = CPoint(centerX - width * 0.8, centerY - height * 0.3);
    points[2] = CPoint(centerX - width * 0.6, centerY - height * 0.5);
    points[3] = CPoint(centerX - width * 0.3, centerY - height * 0.5);
    points[4] = CPoint(centerX - width * 0.1, centerY - height * 0.7);
    points[5] = CPoint(centerX + width * 0.2, centerY - height * 0.6);
    points[6] = CPoint(centerX + width * 0.5, centerY - height * 0.4);
    points[7] = CPoint(centerX + width * 0.7, centerY - height * 0.2);
    points[8] = CPoint(centerX + width * 0.8, centerY);
    points[9] = CPoint(centerX + width * 0.7, centerY + height * 0.3);
    points[10] = CPoint(centerX + width * 0.4, centerY + height * 0.4);
    points[11] = CPoint(centerX, centerY + height * 0.3);
    points[12] = CPoint(centerX - width * 0.4, centerY + height * 0.2);

    dc.BeginPath();
    dc.PolyBezier(points, 13);
    dc.CloseFigure();
    dc.EndPath();

    // 仅描边，不填充
    dc.StrokePath();
}

// 绘制波浪线
void CDrawingBoard20220777View::DrawWave(CDC& dc, CPoint start, CPoint end, double amplitude, double wavelength)
{
    dc.MoveTo(start);

    // 计算两点之间的距离和角度
    double dx = end.x - start.x;
    double dy = end.y - start.y;
    double distance = sqrt(dx * dx + dy * dy);
    double angle = atan2(dy, dx);

    // 绘制波浪线
    int steps = (int)(distance / 5);
    for (int i = 1; i <= steps; i++)
    {
        double t = (double)i / steps;
        double x = start.x + dx * t;
        double y = start.y + dy * t + amplitude * sin(t * distance / wavelength * 2 * M_PI);
        dc.LineTo((int)x, (int)y);
    }

    dc.LineTo(end);
}

// 绘制柳叶形
void CDrawingBoard20220777View::DrawWillowLeaf(CDC& dc, CRect rect)
{
    rect.NormalizeRect();
    CPoint center = rect.CenterPoint();
    int width = rect.Width() / 2;
    int height = rect.Height() / 2;

    // 使用贝塞尔曲线绘制柳叶
    CPoint points[4];
    points[0] = CPoint(center.x, center.y - height);
    points[1] = CPoint(center.x - width * 0.8, center.y - height * 0.2);
    points[2] = CPoint(center.x, center.y + height);
    points[3] = CPoint(center.x + width * 0.8, center.y - height * 0.2);

    dc.BeginPath();
    dc.MoveTo(points[0]);
    dc.PolyBezier(points, 4);
    dc.CloseFigure();
    dc.EndPath();
    dc.StrokeAndFillPath();
}

// 绘制菱形
void CDrawingBoard20220777View::DrawDiamond(CDC& dc, CRect rect)
{
    rect.NormalizeRect();
    POINT points[4] = {
        {rect.CenterPoint().x, rect.top},
        {rect.right, rect.CenterPoint().y},
        {rect.CenterPoint().x, rect.bottom},
        {rect.left, rect.CenterPoint().y}
    };

    // 保存当前画刷状态
    CBrush* pOldBrush = nullptr;
    CBrush* pNullBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
    pOldBrush = dc.SelectObject(pNullBrush);

    // 绘制轮廓
    dc.Polygon(points, 4);

    // 恢复之前的画刷
    if (pOldBrush)
    {
        dc.SelectObject(pOldBrush);
    }
}

// 绘制六边形
void CDrawingBoard20220777View::DrawHexagon(CDC& dc, CRect rect)
{
    rect.NormalizeRect();
    CPoint center = rect.CenterPoint();
    int radius = min(rect.Width(), rect.Height()) / 2;

    POINT points[6];
    for (int i = 0; i < 6; i++)
    {
        double angle = 2 * M_PI * i / 6;
        points[i].x = center.x + (int)(radius * cos(angle));
        points[i].y = center.y + (int)(radius * sin(angle));
    }

    // 保存当前画刷状态
    CBrush* pOldBrush = nullptr;
    CBrush* pNullBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
    pOldBrush = dc.SelectObject(pNullBrush);

    // 绘制轮廓
    dc.Polygon(points, 6);

    // 恢复之前的画刷
    if (pOldBrush)
    {
        dc.SelectObject(pOldBrush);
    }
}

// 绘制五边形
void CDrawingBoard20220777View::DrawPentagon(CDC& dc, CRect rect)
{
    rect.NormalizeRect();
    CPoint center = rect.CenterPoint();
    int radius = min(rect.Width(), rect.Height()) / 2;

    POINT points[5];
    for (int i = 0; i < 5; i++)
    {
        double angle = 2 * M_PI * i / 5 - M_PI / 2;
        points[i].x = center.x + (int)(radius * cos(angle));
        points[i].y = center.y + (int)(radius * sin(angle));
    }

    // 保存当前画刷状态
    CBrush* pOldBrush = nullptr;
    CBrush* pNullBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
    pOldBrush = dc.SelectObject(pNullBrush);

    // 绘制轮廓
    dc.Polygon(points, 5);

    // 恢复之前的画刷
    if (pOldBrush)
    {
        dc.SelectObject(pOldBrush);
    }
}

// 绘制炸弹（带引线、火焰和纹理）
// 绘制炸弹（仅轮廓，匹配参考样式：球形+高光+引线+火焰）
void CDrawingBoard20220777View::Drawbomb(CDC& dc, CRect rect)
{
    rect.NormalizeRect();
    CPoint center = rect.CenterPoint();
    // 炸弹主体半径（取矩形宽高最小值的一半）
    int radius = min(rect.Width(), rect.Height()) / 2;

    // 保存原始画笔、画刷（后续恢复）
    CGdiObject* pOldPen = dc.GetCurrentPen();  // 保留原有画笔（颜色不变）
    CGdiObject* pOldBrush = dc.SelectStockObject(NULL_BRUSH); // 空画刷：仅画轮廓，不填充

    // 1. 绘制炸弹主体轮廓（大椭圆）
    dc.Ellipse(
        center.x - radius,
        center.y - radius,
        center.x + radius,
        center.y + radius
    );

    // 2. 绘制高光轮廓（小椭圆，模拟球面高光）
    int highlightRadius = radius / 4; // 高光大小，可微调
    dc.Ellipse(
        center.x + radius / 3,    // 高光位置：右侧偏上
        center.y - radius / 2,
        center.x + radius / 3 + highlightRadius,
        center.y - radius / 2 + highlightRadius
    );

    // 3. 绘制引线轮廓（直线+小椭圆）
    // 引线起点：炸弹左侧
    CPoint fuseStart = { center.x - radius, center.y };
    // 引线拐点：向上延伸后弯曲
    CPoint fuseMid = { center.x - radius, center.y - radius / 2 };
    // 火焰连接点
    CPoint fuseEnd = { center.x - radius - radius / 5, center.y - radius / 2 };

    // 引线直线部分
    dc.MoveTo(fuseStart);
    dc.LineTo(fuseMid);
    // 引线尾部小椭圆（连接火焰）
    dc.Ellipse(
        fuseEnd.x - radius / 10, fuseEnd.y - radius / 10,
        fuseEnd.x + radius / 10, fuseEnd.y + radius / 10
    );

    // 4. 绘制火焰轮廓（三角形+弧线，模拟燃烧效果）
    POINT flamePoints[3] = {
        {fuseEnd.x - radius / 8, fuseEnd.y - radius / 8},  // 火焰左顶点
        {fuseEnd.x - radius / 5, fuseEnd.y - radius / 5},  // 火焰顶点
        {fuseEnd.x - radius / 8, fuseEnd.y - radius / 10}  // 火焰右顶点
    };
    dc.Polyline(flamePoints, 3); // 火焰轮廓线条

    // 5. 可选：用Arc补火焰细节（让火焰更自然）
    dc.MoveTo(flamePoints[0]);
    dc.Arc(
        fuseEnd.x - radius / 5, fuseEnd.y - radius / 5,
        fuseEnd.x - radius / 10, fuseEnd.y - radius / 10,
        flamePoints[0].x, flamePoints[0].y,
        flamePoints[2].x, flamePoints[2].y
    );

    // 恢复原始画刷、画笔
    dc.SelectObject(pOldBrush);
    dc.SelectObject(pOldPen);
}
# include "FillDialog.h"
void CDrawingBoard20220777View::OnFillColor()
{
    // 创建并显示油漆桶配置对话框
    CFillDialog dlg;

    // 设置当前配置
    dlg.m_FillColor = m_FillColor;
    dlg.m_FillTolerance = m_FillTolerance;
    dlg.m_FillContiguous = m_FillContiguous;
    m_DrawType = DrawType::Fill;
    if (dlg.DoModal() == IDOK) {
        // 更新配置
        m_FillColor = dlg.m_FillColor;
        m_FillTolerance = dlg.m_FillTolerance;
        m_FillContiguous = dlg.m_FillContiguous;

        // 可以在这里保存配置到INI文件或注册表
        SaveFillSettings();
    }
}

// 保存油漆桶设置（可选）
void CDrawingBoard20220777View::SaveFillSettings()
{
    CWinApp* pApp = AfxGetApp();
    pApp->WriteProfileInt(_T("FillSettings"), _T("FillColor"), m_FillColor);
    pApp->WriteProfileInt(_T("FillSettings"), _T("FillTolerance"), m_FillTolerance);
    pApp->WriteProfileInt(_T("FillSettings"), _T("FillContiguous"), m_FillContiguous);
}

// 加载油漆桶设置（可选）
void CDrawingBoard20220777View::LoadFillSettings()
{
    CWinApp* pApp = AfxGetApp();
    m_FillColor = pApp->GetProfileInt(_T("FillSettings"), _T("FillColor"), RGB(0, 0, 255));
    m_FillTolerance = pApp->GetProfileInt(_T("FillSettings"), _T("FillTolerance"), 10);
    m_FillContiguous = pApp->GetProfileInt(_T("FillSettings"), _T("FillContiguous"), TRUE);
}
void CDrawingBoard20220777View::FloodFill(CPoint point)
{
    CClientDC dc(this);
    CRect clientRect;
    GetClientRect(&clientRect);

    // 获取目标颜色
    COLORREF targetColor = dc.GetPixel(point);

    // 如果目标颜色和填充颜色相同，则直接返回
    if (IsColorInTolerance(targetColor, m_FillColor, m_FillTolerance))
        return;

    // 使用扫描线填充算法
    std::stack<CPoint> points;
    points.push(point);

    // 创建内存DC用于高效操作
    CDC memDC;
    memDC.CreateCompatibleDC(&dc);
    CBitmap bitmap;
    bitmap.CreateCompatibleBitmap(&dc, clientRect.Width(), clientRect.Height());
    CBitmap* oldBitmap = memDC.SelectObject(&bitmap);

    // 将当前屏幕内容复制到内存DC
    memDC.BitBlt(0, 0, clientRect.Width(), clientRect.Height(), &dc, 0, 0, SRCCOPY);

    //// 填充进度指示器
    //CProgressDlg progressDlg;
    //progressDlg.Create(IDD_PROGRESS_DIALOG, this);
    //progressDlg.SetWindowText(_T("填充中..."));
    //progressDlg.SetRange(0, 100);
    //progressDlg.SetStep(1);

    int totalPixels = clientRect.Width() * clientRect.Height();
    int processed = 0;

    while (!points.empty()) {
        CPoint pt = points.top();
        points.pop();

        int y = pt.y;
        int x = pt.x;

        // 检查当前点是否在有效范围内
        if (x < 0 || x >= clientRect.Width() || y < 0 || y >= clientRect.Height())
            continue;

        // 获取当前点颜色
        COLORREF currentColor = memDC.GetPixel(x, y);

        // 检查是否在容差范围内
        if (!IsColorInTolerance(currentColor, targetColor, m_FillTolerance))
            continue;

        // 向左填充
        int left = x;
        while (left > 0 &&
            IsColorInTolerance(memDC.GetPixel(left - 1, y), targetColor, m_FillTolerance)) {
            left--;
        }

        // 向右填充
        int right = x;
        while (right < clientRect.Width() - 1 &&
            IsColorInTolerance(memDC.GetPixel(right + 1, y), targetColor, m_FillTolerance)) {
            right++;
        }

        // 填充当前扫描线
        for (int i = left; i <= right; i++) {
            memDC.SetPixel(i, y, m_FillColor);
        }

        // 检查上方扫描线
        if (y > 0) {
            for (int i = left; i <= right; i++) {
                if (IsColorInTolerance(memDC.GetPixel(i, y - 1), targetColor, m_FillTolerance)) {
                    points.push(CPoint(i, y - 1));
                }
            }
        }

        // 检查下方扫描线
        if (y < clientRect.Height() - 1) {
            for (int i = left; i <= right; i++) {
                if (IsColorInTolerance(memDC.GetPixel(i, y + 1), targetColor, m_FillTolerance)) {
                    points.push(CPoint(i, y + 1));
                }
            }
        }

        // 更新进度
        processed += (right - left + 1);
        int percent = min(100, processed * 100 / totalPixels);
        //progressDlg.SetPos(percent);
        //progressDlg.PeekAndPump();

        //if (progressDlg.CheckCancelButton()) {
            //break; // 用户取消
        //}
    }

    // 将修改后的位图复制回屏幕
    dc.BitBlt(0, 0, clientRect.Width(), clientRect.Height(), &memDC, 0, 0, SRCCOPY);

    // 清理资源
    memDC.SelectObject(oldBitmap);
    bitmap.DeleteObject();
}

// 检查颜色是否在容差范围内
bool CDrawingBoard20220777View::IsColorInTolerance(COLORREF color1, COLORREF color2, int tolerance)
{
    if (tolerance == 0) {
        return color1 == color2;
    }

    int r1 = GetRValue(color1);
    int g1 = GetGValue(color1);
    int b1 = GetBValue(color1);

    int r2 = GetRValue(color2);
    int g2 = GetGValue(color2);
    int b2 = GetBValue(color2);

    int diffR = abs(r1 - r2);
    int diffG = abs(g1 - g2);
    int diffB = abs(b1 - b2);

    return (diffR <= tolerance &&
        diffG <= tolerance &&
        diffB <= tolerance);
}

void CDrawingBoard20220777View::SetFillColor(COLORREF color)
{
    m_FillColor = color;
}

void CDrawingBoard20220777View::SetFillTolerance(int tolerance)
{
    m_FillTolerance = max(0, min(255, tolerance));
}

void CDrawingBoard20220777View::SetFillContiguous(bool contiguous)
{
    m_FillContiguous = contiguous;
}




void CDrawingBoard20220777View::OnShapeRoundedRect() { m_DrawType = DrawType::RoundedRectangle; }
void CDrawingBoard20220777View::OnShapeHeart() { m_DrawType = DrawType::Heart; }
void CDrawingBoard20220777View::OnShapeStar() { m_DrawType = DrawType::Star; }
void CDrawingBoard20220777View::OnShapeHexagram() { m_DrawType = DrawType::Hexagram; }
void CDrawingBoard20220777View::OnShapeUpArrow() { m_DrawType = DrawType::UpArrow; }
void CDrawingBoard20220777View::OnShapeDownArrow() { m_DrawType = DrawType::DownArrow; }
void CDrawingBoard20220777View::OnShapeLeftArrow() { m_DrawType = DrawType::LeftArrow; }
void CDrawingBoard20220777View::OnShapeRightArrow() { m_DrawType = DrawType::RightArrow; }
void CDrawingBoard20220777View::OnShapeCloud() { m_DrawType = DrawType::Cloud; }
void CDrawingBoard20220777View::OnShapeWave() { m_DrawType = DrawType::Wave; }
void CDrawingBoard20220777View::OnShapeWillowLeaf() { m_DrawType = DrawType::WillowLeaf; }
void CDrawingBoard20220777View::OnShapeDiamond() { m_DrawType = DrawType::Diamond; }
void CDrawingBoard20220777View::OnShapeHexagon() { m_DrawType = DrawType::Hexagon; }
void CDrawingBoard20220777View::OnShapePentagon() { m_DrawType = DrawType::Pentagon; }
void CDrawingBoard20220777View::OnShapebomb() { m_DrawType = DrawType::bomb; }

void CDrawingBoard20220777View::On_SDL_OnDraw() {
    CDC* pDC = new CDC(); // 创建一个 CDC 对象

    isMy = false;
    // 将 CDC* 类型的设备上下文传递给 SDL_OnDraw 函数
    SDL_OnDraw(pDC);

    // 使用完成后，释放资源
    pDC->Detach(); // 从 CDC 对象中分离 HDC

    delete pDC; // 删除 CDC 对象，避免内存泄漏
}

void CDrawingBoard20220777View::On_SDProL_OnDraw() {
    CDC* pDC = new CDC(); // 创建一个 CDC 对象

    isMy = true;
    // 将 CDC* 类型的设备上下文传递给 SDL_OnDraw 函数
    SDL_OnDraw(pDC);

    // 使用完成后，释放资源
    pDC->Detach(); // 从 CDC 对象中分离 HDC

    delete pDC; // 删除 CDC 对象，避免内存泄漏
}




// 计算X坐标的辅助函数
int CDrawingBoard20220777View::CalculateX(int originalX) {

    return centerX - headWidth / 2 + (originalX - headOffsetX) * scale;
}

// 计算Y坐标的辅助函数
int CDrawingBoard20220777View::CalculateY(int originalY) {

    return centerY - headHeight / 2 + (originalY - headOffsetY) * scale;
}

// 水平镜像绝对坐标计算函数
int CDrawingBoard20220777View::MirrorXAbs(int originalX) {
    return 2 * centerX - originalX;
}

// 水平镜像相对坐标计算函数
int CDrawingBoard20220777View::MirrorX(int originalX) {
    return MirrorXAbs(CalculateX(originalX));
}

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
// 应用画笔样式（虚线、点线等）
void CDrawingBoard20220777View::ApplyPenStyle(CDC* pDC, const LOGPEN& logPen, int cx, int cy, int a, int b, int penWidth, COLORREF transparentColor)
{
    // 只处理非实线样式
    if (logPen.lopnStyle == PS_SOLID) return;

    // 计算轮廓区域的内外边界
    double outerRadius = 1.0 + 0.5 / min(a, b);
    double innerRadius = (a > penWidth / 2.0 && b > penWidth / 2.0) ?
        1.0 - (penWidth) / (2.0 * min(a, b)) : 0;

    int a2 = a * a;
    int b2 = b * b;

    // 计算椭圆周长（近似值）用于样式重复
    double circumference = 2 * M_PI * sqrt((a2 + b2) / 2.0);

    // 根据画笔样式创建掩码
    for (int y = 0; y < 2 * b + 1; y++) {
        for (int x = 0; x < 2 * a + 1; x++) {
            int dx = x - a;
            int dy = y - b;

            // 计算点到椭圆中心的距离比例
            double dist = (double)(dx * dx) / a2 + (double)(dy * dy) / b2;

            // 如果在轮廓区域内
            if (dist >= innerRadius * innerRadius && dist <= outerRadius * outerRadius) {
                // 计算点在椭圆上的参数位置（近似）
                double t = atan2(dy * a, dx * b);
                if (t < 0) t += 2 * M_PI;

                // 将参数位置映射到周长上的位置
                double position = t * circumference / (2 * M_PI);

                // 根据画笔样式决定是否保留此像素
                bool keepPixel = true;

                switch (logPen.lopnStyle) {
                case PS_DASH:
                    // 虚线样式 - 调整为更接近GDI的实现
                    keepPixel = fmod(position, 10.0) < 5.0;
                    break;

                case PS_DOT:
                    // 点线样式 - 调整为更接近GDI的实现
                    keepPixel = fmod(position, 4.0) < 1.0;
                    break;

                case PS_DASHDOT:
                    // 点划线样式 - 调整为更接近GDI的实现
                    keepPixel = (fmod(position, 14.0) < 8.0) || (fmod(position, 14.0) >= 10.0 && fmod(position, 14.0) < 11.0);
                    break;

                case PS_DASHDOTDOT:
                    // 双点划线样式 - 调整为更接近GDI的实现
                    keepPixel = (fmod(position, 16.0) < 8.0) ||
                        (fmod(position, 16.0) >= 10.0 && fmod(position, 16.0) < 11.0) ||
                        (fmod(position, 16.0) >= 13.0 && fmod(position, 16.0) < 14.0);
                    break;
                }

                // 如果不保留此像素，则设为透明色
                if (!keepPixel) {
                    pDC->SetPixel(cx + dx, cy + dy, transparentColor);
                }
            }
        }
    }
}


void CDrawingBoard20220777View::MyEllipse(CDC* pDC, int left, int top, int right, int bottom)
{
    if (!isMy) {
        pDC->Ellipse(left, top, right, bottom);
        return;
    }
    // 坐标验证与交换
    if (left > right) { int temp = left; left = right; right = temp; }
    if (top > bottom) { int temp = top; top = bottom; bottom = temp; }

    // 获取当前画笔（包括样式、宽度和颜色）
    LOGPEN logPen = { 0 };
    CPen* pCurrentPen = pDC->GetCurrentPen();
    if (pCurrentPen) {
        pCurrentPen->GetLogPen(&logPen);
    }

    // 获取当前画刷
    COLORREF brushColor = RGB(255, 255, 255);
    bool fillEllipse = false;
    CBrush* pCurrentBrush = pDC->GetCurrentBrush();
    if (pCurrentBrush) {
        LOGBRUSH logBrush = { 0 };
        pCurrentBrush->GetLogBrush(&logBrush);

        switch (logBrush.lbStyle) {
        case BS_SOLID:
            brushColor = logBrush.lbColor;
            fillEllipse = true;
            break;
        case BS_HOLLOW:
            fillEllipse = false;
            break;
        case BS_HATCHED:
            brushColor = logBrush.lbColor;
            fillEllipse = true;
            break;
        default:
            fillEllipse = false;
            break;
        }
    }

    // 椭圆参数计算
    int width = right - left;
    int height = bottom - top;
    int cx = left + width / 2;
    int cy = top + height / 2;
    int a = width / 2;
    int b = height / 2;
    int a2 = a * a;
    int b2 = b * b;

    // 画笔宽度处理 - 调整计算方式使其与GDI更接近
    int penWidth = logPen.lopnWidth.x;
    if (penWidth < 1) penWidth = 1;

    // 创建位图存储椭圆轮廓数据
    CBitmap bitmap;
    bitmap.CreateCompatibleBitmap(pDC, width + penWidth * 2, height + penWidth * 2);
    CDC memDC;
    memDC.CreateCompatibleDC(pDC);
    memDC.SelectObject(&bitmap);

    // 填充背景为透明色
    COLORREF transparentColor = RGB(255, 0, 255); // 选择一个不会使用的颜色作为透明色
    memDC.FillSolidRect(0, 0, width + penWidth * 2, height + penWidth * 2, transparentColor);


    // 优化的椭圆内部填充
    if (fillEllipse) {
        // 计算内边界（排除轮廓区域）
        double innerFillRadius = 1.0 - (penWidth) / (2.0 * min(a, b));
        if (innerFillRadius < 0) innerFillRadius = 0;
        double innerFillRadius2 = innerFillRadius * innerFillRadius;

        // 使用扫描线算法填充内部
        for (int y = top; y <= bottom; y++) {
            int dy = y - cy;
            if (abs(dy) > b) continue;

            // 计算椭圆边界
            double xd = a * sqrt(1.0 - (double)(dy * dy) / b2);
            int startX = (int)ceil(cx - xd);
            int endX = (int)floor(cx + xd);

            // 扫描线填充
            for (int x = startX; x <= endX; x++) {
                // 计算点到椭圆中心的距离比例
                double dist = (double)(x - cx) * (x - cx) / a2 +
                    (double)(dy * dy) / b2;

                // 只填充在内边界内部的区域
                if (dist < innerFillRadius2) {
                    pDC->SetPixel(x, y, brushColor);
                }
            }
        }
    }

    // 计算相对于内存DC的中心点
    int memCx = a + penWidth;
    int memCy = b + penWidth;

    // 高质量椭圆轮廓绘制 - 使用改进的区域填充方法
    // 1. 计算轮廓的内外边界（调整系数使其与GDI更接近）
    double scaleFactor = 1.0 + (penWidth - 1) / 2.0;
    double outerRadius = 1.0 + 0.5 / min(a, b);
    double innerRadius = (a > penWidth / 2.0 && b > penWidth / 2.0) ?
        1.0 - (penWidth - 1) / (0.8 * min(a, b)) : 0;

    // 2. 填充整个椭圆区域
    for (int y = 0; y < height + penWidth * 2; y++) {
        for (int x = 0; x < width + penWidth * 2; x++) {
            // 计算相对于椭圆中心的坐标
            int dx = x - memCx;
            int dy = y - memCy;

            // 计算点到椭圆中心的距离比例
            double dist = (double)(dx * dx) / a2 + (double)(dy * dy) / b2;

            // 调整边界计算，使其与GDI更接近
            if (dist >= innerRadius * innerRadius && dist <= outerRadius * outerRadius) {
                memDC.SetPixel(x, y, logPen.lopnColor);
            }
        }
    }

    // 3. 应用画笔样式（虚线、点线等）
    ApplyPenStyle(&memDC, logPen, memCx, memCy, a, b, penWidth, transparentColor);

    // 4. 将内存中的椭圆轮廓复制到实际DC
    for (int y = 0; y < height + penWidth * 2; y++) {
        for (int x = 0; x < width + penWidth * 2; x++) {
            COLORREF color = memDC.GetPixel(x, y);
            if (color != transparentColor) {
                pDC->SetPixel(left + x - penWidth, top + y - penWidth, color);
            }
        }
    }

    // 清理资源
    memDC.DeleteDC();
    bitmap.DeleteObject();


}



void CDrawingBoard20220777View::SDL_OnDraw(CDC* pDC)
{
    DL = !DL;
    OnReload();
}



